"use strict";

const path = require("path");
const utils = require("@zreact-cli/utils");
const pkgDir = require("pkg-dir").sync;
const npminstall = require("npminstall");
const pathExists = require("path-exists").sync;
const fse = require("fs-extra");
const formatPath = require("@zreact-cli/formatPath");
const {
  getDefaultRegistry,
  getNpmLatestVersion,
} = require("@zreact-cli/getNpmInfo");

class Package {
  constructor(options) {
    if (!options || !utils.isObject(options)) {
      throw new Error("Package类options不能为空");
    }
    //package路径
    this.targetPath = options.targetPath;
    //package存储路径
    this.storePath = options.storePath;
    //package的name
    this.packageName = options.packageName;
    //package的version
    this.packageVersion = options.packageVersion;
    //package的缓存目录前缀
    this.cacheFilePathPrefix = this.packageName.replace(/\//, "_");
  }

  //把latest 转成具体的版本号
  async prepare() {
    //有缓存路径但是不存在
    if (this.storePath && !pathExists(this.storePath)) {
      fse.mkdirpSync(this.storePath);
    }
    if (this.packageVersion === "latest") {
      this.packageVersion = await getNpmLatestVersion(this.packageName);
    }
  }

  get cacheFilePath() {
    return path.resolve(
      this.storePath,
      `_${this.cacheFilePathPrefix}@${this.packageVersion}@${this.packageName}`
    );
  }

  getSpecificCacheFilePath(version) {
    return path.resolve(
      this.storePath,
      `_${this.cacheFilePathPrefix}@${version}@${this.packageName}`
    );
  }

  //判断当前Package是否存在
  async exists() {
    if (this.storePath) {
      //缓存莫斯
      await this.prepare();
      return pathExists(this.cacheFilePath);
    } else {
      return pathExists(this.targetPath);
    }
  }
  //安装package
  async install() {
    await this.prepare();
    await npminstall({
      root: this.targetPath,
      storeDir: this.storePath,
      registry: getDefaultRegistry(),
      pkgs: [{ name: this.packageName, version: this.packageVersion }],
    });
  }
  //更新package
  async update() {
    //获取最新版本号
    await this.prepare();
    //查询最新版本号对应的文件
    const newPackageVersion = await getNpmLatestVersion(this.packageName);
    const latestFilePath = this.getSpecificCacheFilePath(newPackageVersion);
    if (!pathExists(latestFilePath)) {
      await npminstall({
        root: this.targetPath,
        storeDir: this.storePath,
        registry: getDefaultRegistry(),
        pkgs: [{ name: this.packageName, version: newPackageVersion }],
      });
      this.packageVersion = newPackageVersion;
    } else {
      this.packageVersion = newPackageVersion;
    }

    return latestFilePath;
  }

  //获取入口文件路径
  getRootFilePath() {
    function _getRootFile(targetPath) {
      // 1. 获取package.json的所在目录  - pkg-dir
      const dir = pkgDir(targetPath);
      if (dir) {
        // 2. 读取package.json - require
        const pkgFile = require(path.resolve(dir, "package.json"));
        // 3. main/lib -> path
        if (pkgFile && (pkgFile.main || pkgFile.lib)) {
          // 4. 路径兼容(macOS/windows)
          return formatPath(path.resolve(dir, pkgFile.main));
        }
      }
    }

    if (this.storePath) {
      return _getRootFile(this.cacheFilePath);
    } else {
      return _getRootFile(this.targetPath);
    }
  }
}

module.exports = Package;
